package com.xc.erp.modules.erp.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xc.erp.common.utils.SecurityUtils;
import com.xc.erp.modules.erp.domain.dto.BillParam;
import com.xc.erp.modules.erp.domain.pojo.*;
import com.xc.erp.modules.erp.domain.vo.DepotConditionVo;
import com.xc.erp.modules.erp.domain.vo.ResultDepotMaterialVo;
import com.xc.erp.modules.erp.mapper.JshDepotHeadMapper;
import com.xc.erp.modules.erp.mapper.JshMaterialCurrentStockMapper;
import com.xc.erp.modules.erp.mapper.JshSupplierMapper;
import com.xc.erp.modules.erp.service.*;
import org.apache.commons.collections4.functors.OnePredicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author Administrator
 * @description 针对表【jsh_depot_head(单据主表)】的数据库操作Service实现
 * @createDate 2022-12-10 10:05:42
 */
@Service
public class JshDepotHeadServiceImpl extends ServiceImpl<JshDepotHeadMapper, JshDepotHead> implements JshDepotHeadService {

    public QueryWrapper<JshDepotHead> depotHeadWrapper(DepotConditionVo depotCondition) {
        QueryWrapper<JshDepotHead> wrapper = new QueryWrapper<JshDepotHead>().eq("type", depotCondition.getType()).eq("sub_type", depotCondition.getSubType()).eq("delete_flag", 0);
        if (depotCondition.getNumber() != null && !"".equals(depotCondition.getNumber())) {
            wrapper.like("number", depotCondition.getNumber());
        }
        if (depotCondition.getEndTime() != null && !"".equals(depotCondition.getEndTime())) {
            wrapper.between("create_time", depotCondition.getBeginTime(), depotCondition.getEndTime());
        }
        if (depotCondition.getOrganId() != null && !"".equals(depotCondition.getOrganId())) {
            wrapper.eq("organ_id", depotCondition.getOrganId());
        }
        if (depotCondition.getCreator() != null && !"".equals(depotCondition.getCreator())) {
            wrapper.eq("creator", depotCondition.getCreator());
        }
        if (depotCondition.getLinkNumber() != null && !"".equals(depotCondition.getLinkNumber())) {
            wrapper.like("link_number", depotCondition.getLinkNumber());
        }
        if (depotCondition.getStatus() != null && !"".equals(depotCondition.getStatus())) {
            wrapper.eq("status", depotCondition.getStatus());
        }
        if (depotCondition.getRemak() != null && !"".equals(depotCondition.getRemak())) {
            wrapper.like("remak", depotCondition.getRemak());
        }
        return wrapper;
    }

    @Autowired
    private JshUserService jshUserService;

    @Autowired
    private JshMaterialCurrentStockService jshMaterialCurrentStockService;
    @Autowired
    private JshMaterialService jshMaterialService;

    @Autowired
    private JshSupplierMapper jshSupplierMapper;
    @Autowired
    private JshDepotItemService jshDepotItemService;

    @Override
    public Page<JshDepotHead> jshDepotHeadList(DepotConditionVo depotCondition) {
        Page<JshDepotHead> page = new Page<>(depotCondition.getCurrentPage(), depotCondition.getPageSize());
        List<Long> idList = null;
        if (depotCondition.getMaterialParam() != null && !"".equals(depotCondition.getMaterialParam())) {
            idList = jshMaterialService.materialBylikeDepotList(depotCondition.getMaterialParam());
        }
        List<Long> finalIdList = idList;
        QueryWrapper<JshDepotItem> queryWrapper = new QueryWrapper<JshDepotItem>();
        if (depotCondition.getDepotId() != null && !"".equals(depotCondition.getDepotId())) {
            queryWrapper.eq("depot_id", depotCondition.getDepotId());
        }
        if (finalIdList != null) {
            if (finalIdList.size() == 0)
                queryWrapper.eq("0", "1");
            else
                queryWrapper.in("material_id", finalIdList);
        }
        List<JshDepotItem> jshDepotItems = jshDepotItemService.list(queryWrapper);
        QueryWrapper<JshDepotHead> wrapper = depotHeadWrapper(depotCondition);
        if (jshDepotItems.size() > 0) {
            wrapper = wrapper.in("id", jshDepotItems.stream().map(jshDepotItem -> jshDepotItem.getHeaderId()).collect(Collectors.toList()));
        } else {
            wrapper = wrapper.eq("1", "2");
        }
        page = page(page, wrapper);
        for (int i = 0; i < page.getRecords().size(); i++) {
            if (page.getRecords().get(i).getOrganId() != null)
                page.getRecords().get(i).setOrganName(jshSupplierMapper.selectOne(new QueryWrapper<JshSupplier>().eq("id", page.getRecords().get(i).getOrganId())).getSupplier());
            List<JshDepotItem> items = jshDepotItemService.list(new QueryWrapper<JshDepotItem>().eq("header_id", page.getRecords().get(i).getId()));
            BigDecimal operNumber = BigDecimal.ZERO;
            BigDecimal allPrice = BigDecimal.ZERO;
            BigDecimal totalTaxLastMoney = BigDecimal.ZERO;
            for (JshDepotItem jshDepotItem : items) {
                operNumber = operNumber.add(jshDepotItem.getOperNumber());
                allPrice = allPrice.add(jshDepotItem.getAllPrice());
                //获取含税合计
                totalTaxLastMoney = totalTaxLastMoney.add(jshDepotItem.getTaxLastMoney() == null ? BigDecimal.ZERO : jshDepotItem.getTaxLastMoney());
            }
            page.getRecords().get(i).setNum(operNumber);
            page.getRecords().get(i).setAllPrice(allPrice);
            page.getRecords().get(i).setTotalTaxLastMoney(totalTaxLastMoney);
            List<Long> materialIds = items.stream().map(jshDepotItem -> jshDepotItem.getMaterialId()).collect(Collectors.toList());
            List<JshMaterial> materials = jshMaterialService.list(new QueryWrapper<JshMaterial>().in("id", materialIds));
            String materialInfo = "";
            for (JshMaterial jshMaterial : materials) {
                materialInfo += jshMaterial.getName() + " " + jshMaterial.getModel() + " " + jshMaterial.getStandard();
                if (materials.size() > 1)
                    materialInfo += " ";
            }
            page.getRecords().get(i).setMaterialsList(materialInfo);
            //判断支付订单是为null
            if(page.getRecords().get(i).getDeposit() == null) {
                page.getRecords().get(i).setDeposit(BigDecimal.ZERO);
            }
            //获取操作员
            page.getRecords().get(i).setCreatorName(jshUserService.getById(page.getRecords().get(i).getCreator()).getLoginName());
        }
        return page;
    }

    @Autowired
    private JshMaterialCurrentStockMapper jshMaterialCurrentStockMapper;

    @Autowired
    private JshDepotHeadMapper jshDepotHeadMapper;

    @Override
    @Transactional
    public boolean addDepotHeadAndDetail(JshDepotHead info) {
        if (info.getId() == null) {
            info.setCreateTime(new Date());
            info.setOperTime(new Date());
            info.setDefaultNumber(info.getNumber());
            info.setCreator(SecurityUtils.getUserId());
            info.setTenantId(SecurityUtils.getLoginUser().getJshUser().getTenantId());
        }
        info.setPayType(info.getPayType() == null ? "现付" : info.getPayType());
//        if (info.getSubType().equals("组装单") || info.getSubType().equals("拆卸单") || info.getSubType().equals("调拨")) {
//            throw new RuntimeException("抱歉，" + info.getSubType() + "不能选择批号或序列号商品，建议走其它入库和出库单");
//        }
        BigDecimal totalPrice = new BigDecimal(0.0);
        for (ResultDepotMaterialVo resultDepotMaterialVo : info.getJshDepotItemList()) {
            totalPrice = totalPrice.add(resultDepotMaterialVo.getBillPrice());
        }
        info.setTotalPrice(totalPrice);
        boolean save = false;
        if (info.getId() == null)
            save = jshDepotHeadMapper.insert(info) > 0;
        else
            save = jshDepotHeadMapper.updateById(info) > 0;
        if (info.getJshDepotItemList() != null && info.getJshDepotItemList().size() > 0) {
            for (ResultDepotMaterialVo resultDepotMaterialVo : info.getJshDepotItemList()) {
                JshDepotItem jshDepotItem = new JshDepotItem();
                if (resultDepotMaterialVo.getMaterialType() != null)
                    jshDepotItem.setMaterialType(resultDepotMaterialVo.getMaterialType());
                if (resultDepotMaterialVo.getAnotherDepotId() != null)
                    jshDepotItem.setAnotherDepotId(resultDepotMaterialVo.getAnotherDepotId());
                jshDepotItem.setHeaderId(info.getId());
                jshDepotItem.setDepotId(resultDepotMaterialVo.getDepotId());
                jshDepotItem.setMaterialId(resultDepotMaterialVo.getMaterialId());
                jshDepotItem.setMaterialExtendId(resultDepotMaterialVo.getId());
                jshDepotItem.setAllPrice(resultDepotMaterialVo.getBillPrice());
                jshDepotItem.setUnitPrice(resultDepotMaterialVo.getUnitPrice());
                jshDepotItem.setMaterialUnit(resultDepotMaterialVo.getUnit());
                jshDepotItem.setSku(resultDepotMaterialVo.getSku());
                resultDepotMaterialVo.setOperNumber(new BigDecimal(1));
                jshDepotItem.setBasicNumber(resultDepotMaterialVo.getOperNumber());
                jshDepotItem.setDeleteFlag("0");
                jshDepotItem.setRemark(resultDepotMaterialVo.getRemark());
                jshDepotItem.setOperNumber(resultDepotMaterialVo.getOperNumber());
                if (!StringUtils.isEmpty(resultDepotMaterialVo.getMBarCode())) {
                    ResultDepotMaterialVo resultDepotMaterialVo2 = jshMaterialService.getMaterialByBarCode(resultDepotMaterialVo.getMBarCode(), jshDepotItem.getDepotId());
                    jshDepotItem.setMaterialId(resultDepotMaterialVo2.getMaterialId());
                    jshDepotItem.setMaterialExtendId(resultDepotMaterialVo2.getId());
                    //库存
                    List<Long> ruKu = jshDepotHeadMapper.selectList(new QueryWrapper<JshDepotHead>().eq("type", "入库")).stream().map(JshDepotHead::getId).collect(Collectors.toList());
                    List<Long> chuKu = jshDepotHeadMapper.selectList(new QueryWrapper<JshDepotHead>().eq("type", "出库")).stream().map(JshDepotHead::getId).collect(Collectors.toList());
                    int stock = jshDepotItemService.list(new QueryWrapper<JshDepotItem>().in("header_id", ruKu)).stream().filter(friend -> friend.getOperNumber() != null).mapToInt(value -> value.getOperNumber().intValue()).sum() - jshDepotItemService.list(new QueryWrapper<JshDepotItem>().in("header_id", chuKu)).stream().filter(friend -> friend.getOperNumber() != null).mapToInt(value -> value.getOperNumber().intValue()).sum();

                    JshMaterialCurrentStock jshMaterialCurrentStock = new JshMaterialCurrentStock();
                    jshMaterialCurrentStock.setDepotId(resultDepotMaterialVo2.getDepotId());
                    jshDepotItemService.list(new QueryWrapper<>());
                    if (info.getType().equals("入库"))
                        jshMaterialCurrentStock.setCurrentNumber(resultDepotMaterialVo.getOperNumber().add(new BigDecimal(stock)));
                    else if (info.getType().equals("出库"))
                        jshMaterialCurrentStock.setCurrentNumber(new BigDecimal(stock).subtract(resultDepotMaterialVo.getOperNumber()));
                    jshMaterialCurrentStock.setDeleteFlag("0");
                    jshMaterialCurrentStock.setTenantId(SecurityUtils.getLoginUser().getJshUser().getTenantId());
                    if (info.getType().equals("出库") || info.getType().equals("入库")) {
                        JshMaterialCurrentStock one = jshMaterialCurrentStockService.getOne(new QueryWrapper<JshMaterialCurrentStock>().eq("material_id", resultDepotMaterialVo2.getMaterialId()).eq("depot_id", resultDepotMaterialVo2.getDepotId()));
                        if (one == null)
                            jshMaterialCurrentStockService.save(jshMaterialCurrentStock);
                        else
                            jshMaterialCurrentStockService.update(new UpdateWrapper<JshMaterialCurrentStock>().eq("material_id", resultDepotMaterialVo2.getMaterialId()).setSql("current_number=current_number+" + jshMaterialCurrentStock.getCurrentNumber()));
                    }

                }
                jshDepotItem.setTenantId(SecurityUtils.getLoginUser().getJshUser().getTenantId());
                boolean b = jshDepotItemService.save(jshDepotItem);
                if (!b) {
                    return b;
                }
            }
        }
        jshSequenceService.updateBuildOnlyNumber();
        return save;
    }

    @Autowired
    JshSequenceService jshSequenceService;

    @Override
    public boolean updateBatchSetStatus(String ids[], String status) {
        return update(new UpdateWrapper<JshDepotHead>().in("id", ids).set("status", status));
    }

    @Transactional
    @Override
    public boolean delIds(String[] ids) {
        boolean b = update(new UpdateWrapper<JshDepotHead>().in("id", ids).set("delete_flag", 1));
        jshDepotItemService.update(new UpdateWrapper<JshDepotItem>().in("header_id", ids).set("delete_flag", 1));
        List<JshDepotItem> jshDepotItems = jshDepotItemService.list(new QueryWrapper<JshDepotItem>().in("header_id", ids));
        for (JshDepotItem jshDepotItem : jshDepotItems) {
            JshMaterialCurrentStock jshMaterialCurrentStock = new JshMaterialCurrentStock();
            jshMaterialCurrentStock.setMaterialId(jshDepotItem.getMaterialId());
            jshMaterialCurrentStock.setDepotId(jshDepotItem.getDepotId());
            jshMaterialCurrentStock.setDeleteFlag("0");
            jshMaterialCurrentStock.setTenantId(SecurityUtils.getLoginUser().getJshUser().getTenantId());
            jshMaterialCurrentStockService.save(jshMaterialCurrentStock);
        }
        return b;
    }

    @Transactional
    @Override
    public boolean updateDepotHeadAndDetail(JshDepotHead info) {
        for (ResultDepotMaterialVo resultDepotMaterialVo : info.getJshDepotItemList()) {
            jshDepotItemService.remove(new QueryWrapper<JshDepotItem>().eq("material_id", resultDepotMaterialVo.getMaterialId()).eq("header_id", info.getId()));
        }
        return addDepotHeadAndDetail(info);

    }
}




